package com.sheep.api.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.w3c.dom.Document;
/**
 * jaxb  xml  Object   互转
 * @author charlie
 *
 */
public class JAXBUtils {
	/**
	 * 对象转变为xml
	 * @param <T>
	 * @param dto
	 * @param xml
	 * @throws javax.xml.bind.JAXBException
	 * @throws java.io.IOException
	 */
	 public static <T> void dtoToXml(T dto,String xml)throws JAXBException,IOException{
	    JAXBContext context = JAXBContext.newInstance(dto.getClass());
	    Marshaller m = context.createMarshaller();
	    OutputStream out = new FileOutputStream(xml);
	    m.marshal(dto,out);
	    out.close();
	 }
	 
	 /**
	  * xml转换为对象
	  * @param <T>
	  * @param xml
	  * @param clazz
	  * @return
	  * @throws javax.xml.bind.JAXBException
	  * @throws java.io.IOException
	  */
	 @SuppressWarnings("unchecked")
	 public static <T> T xmlToDto(String xml,Class<T> clazz)throws JAXBException,IOException{
	    JAXBContext context = JAXBContext.newInstance(clazz);
	    Unmarshaller um = context.createUnmarshaller();
	    InputStream in =  new   ByteArrayInputStream(xml.getBytes("UTF-8"));
	    T t = (T)um.unmarshal(in);
	    in.close();
	    return t;
	 }
	 
	 /**
	  * xml String 转化为对象
	  * @param <T>
	  * @param xmlStr
	  * @param clazz
	  * @return
	  * @throws javax.xml.bind.JAXBException
	  */
	 @SuppressWarnings("unchecked")
	 public static <T> T xmlStringToDto(String xmlStr,Class<T> clazz) throws JAXBException{
		 JAXBContext jc = JAXBContext.newInstance(clazz);
		 Unmarshaller u = jc.createUnmarshaller();
		 T ret = (T)u.unmarshal( new StreamSource( new StringReader( xmlStr ) ) );
		 return ret;
	 }
	 
	 /**
	  * 对象转化为xml String 
	  * @param <T>
	  * @param dto
	  * @return
	  * @throws javax.xml.bind.JAXBException
	  */
	 public static <T> String dtoToXmlString(T dto) throws JAXBException{
	  //xml String 转化为对象
		 JAXBContext jc = JAXBContext.newInstance(dto.getClass());
		 Marshaller m = jc.createMarshaller();
		 m.setProperty("jaxb.formatted.output", true);
		 ByteArrayOutputStream  out = new ByteArrayOutputStream();
		 Result result = new StreamResult(out);
		 m.marshal(dto, result);
		 return new String(out.toByteArray());
	 }
	 
	 /**
	  * 对象转变为byte数组 
	  * @param <T>
	  * @param dto
	  * @return
	  * @throws javax.xml.bind.JAXBException
	  */
	 public static <T> byte[] dtoToByteArray(T dto) throws JAXBException{
        JAXBContext context = JAXBContext.newInstance(dto.getClass());
        Marshaller m = context.createMarshaller();
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        m.marshal(dto, out);
        return out.toByteArray();
	 }
	 
	 /**
	  * byte数组转变为对象
	  * @param <T>
	  * @param arr
	  * @param clazz
	  * @return
	  * @throws javax.xml.bind.JAXBException
	  */
	 @SuppressWarnings("unchecked")
	 public static <T> T byteArrayToDto(byte[] arr,Class<T> clazz) throws JAXBException{
		 JAXBContext context = JAXBContext.newInstance(clazz);
		 Unmarshaller um = context.createUnmarshaller();
		 ByteArrayInputStream in = new ByteArrayInputStream(arr);
		 T ret = (T)um.unmarshal(in);
		 return ret;
	 }
	 
	 /**
	  * dom转化成dto
	  * @param <T>
	  * @param dom
	  * @param clazz
	  * @return
	  * @throws javax.xml.bind.JAXBException
	  */
	 @SuppressWarnings("unchecked")
	 public static <T> T domToDto(Document dom,Class<T> clazz)throws JAXBException{
	       JAXBContext context = JAXBContext.newInstance(clazz);
	       Unmarshaller um = context.createUnmarshaller();
	       T ret = (T)um.unmarshal(dom);
	       return ret;
	 }
	 
	 /**
	  * dto转化成dom
	  * @param <T>
	  * @param dto
	  * @return
	  * @throws javax.xml.bind.JAXBException
	  * @throws javax.xml.parsers.ParserConfigurationException
	  */
	 public static <T> Document dtoToDom(T dto) throws JAXBException, ParserConfigurationException{
		  JAXBContext context = JAXBContext.newInstance(dto.getClass());
		  Marshaller m = context.createMarshaller();
		  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		  DocumentBuilder db = dbf.newDocumentBuilder();
		  Document doc = db.newDocument();
		  m.marshal( dto, doc );
		  return doc;
	 }
	 
	 /**
	  * dom转化成xml string
	  * @param <T>
	  * @param dom
	  * @param clazz
	  * @return
	  * @throws javax.xml.bind.JAXBException
	  */
	 public static <T> String domToString(Document dom,Class<T> clazz) throws JAXBException{
		  T dto = domToDto(dom,clazz);
		  return dtoToXmlString(dto);
	 }
	 
	 /**
	  * xml string转化成dom
	  * @param <T>
	  * @param xmlStr
	  * @param clazz
	  * @return
	  * @throws javax.xml.bind.JAXBException
	  * @throws javax.xml.parsers.ParserConfigurationException
	  */
	 public static <T> Document stringToDom(String xmlStr,Class<T> clazz) throws JAXBException, ParserConfigurationException{
		  T dto = xmlStringToDto(xmlStr,clazz);
		  return dtoToDom(dto);
		
	}

//    public static void main(String[] args){
//        ADSBResultBean result = new ADSBResultBean();
//        List<ADSBBean> list = new ArrayList<ADSBBean>();
//
//        ADSBBean b1 = new ADSBBean();
//        b1.setAn("B-1234");
//        b1.setFi("MU4321");
//        b1.setLat(1.234);
//        b1.setLon(2.345);
//        ADSBBean b2 = new ADSBBean();
//        b2.setAn("B-2234");
//        b2.setFi("MU4322");
//        b2.setLat(1.234);
//        b2.setLon(2.345);
//        result.getList().add(b1);
//        result.getList().add(b2);
////        list.add(b1);
////        list.add(b2);
//        try {
//            System.out.println(JAXBUtils.dtoToXmlString(result));
//        } catch (JAXBException e) {
//            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
//        }
//    }
}
